package server

import (
	"bytes"
	"fmt"
	"gin_gorm/web/conf"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	"os"
	"path/filepath"
)

const (
	ConfigDefaultFile = "config.yaml"
	ConfigTestFile    = "config.test.yaml"
	ConfigDevFile     = "config.dev.yaml"
	ConfigProdFile    = "config.prod.yaml"
)

const (
	DevMode  = "dev"
	TestMode = "test"
	ProdMode = "prod"

	DefaultMode = ""
)

func ReadProdConfig(prodFilePath string) ([]byte, error) {
	readFile, err := os.ReadFile(prodFilePath)
	if err != nil {
		fmt.Println("open prod config err ", err)
		return nil, err
	}
	fmt.Println("read config success")
	return readFile, nil

}

func readConfig(mode, path string) ([]byte, error) {
	data := make([]byte, 0)
	if mode == ProdMode {
		prodConfig, err := ReadProdConfig(path)
		if err != nil {
			fmt.Printf("read prod config err  路径:%s ,error:%v\n", path, err)
			return nil, err
		}
		data = prodConfig
	} else {
		file, err := os.ReadFile(path)
		if err != nil {
			fmt.Printf("read  config err  路径:%s ,error:%v\n", path, err)
			return nil, err
		}
		data = file
	}

	return data, nil
}
func NewViper(mode string, path ...string) *conf.Config {
	var config string
	switch mode {
	case DevMode:
		config = filepath.Join("config", ConfigDefaultFile)
		fmt.Printf("您正在使用%s环境,config的路径为%s\n", DevMode, ConfigDefaultFile)
	case ProdMode:
		config = filepath.Join("config", ConfigProdFile)
		fmt.Printf("您正在使用%s环境,config的路径为%s\n", ProdMode, ConfigProdFile)
	case TestMode:
		config = filepath.Join("config", ConfigTestFile)
		fmt.Printf("您正在使用%s环境,config的路径为%s\n", TestMode, ConfigTestFile)
	default:
		config = filepath.Join("config", ConfigDefaultFile)
		fmt.Printf("您正在使用%s环境,config的路径为%s\n", ConfigDefaultFile, config)
	}
	if len(path) > 0 {
		config = path[0]
	}
	v := viper.New()
	v.SetConfigFile(config)
	v.SetConfigType("yaml")
	data, err := readConfig(mode, config)
	if err != nil {
		panic(fmt.Errorf("Fatal error config file: %s \n", err))
	}
	err = v.ReadConfig(bytes.NewReader(data))
	if err != nil {
		panic(fmt.Errorf("Fatal error config file: %s \n", err))
	}

	conf := new(conf.Config)
	if err = v.Unmarshal(&conf); err != nil {
		fmt.Println("logs config err")
	}
	v.WatchConfig()
	v.OnConfigChange(func(e fsnotify.Event) {
		data, err = readConfig(mode, config)
		if err != nil {
			fmt.Printf("Fatal error config file: %s \n", err)
			return
		}
		err = v.ReadConfig(bytes.NewReader(data))
		if err != nil {
			fmt.Printf("Fatal error config file: %s \n", err)
			return
		}
		if err = v.Unmarshal(&conf); err != nil {
			fmt.Printf("Fatal error config file: %s \n", err)
			return
		} else {
			fmt.Println("reload config success", config)
		}
	})
	return conf
}
func RunServe() {
	var conf = NewViper("dev111")
	app, f, err := wireApp(conf)
	if err != nil {

	}
	defer f()
	app.StartApp()
}
